package utils

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/md5"
	"crypto/rand"
	"crypto/tls"
	"encoding/hex"
	"fmt"
	"github.com/snluu/uuid"
	"io"
	"log"
	"net"
	"net/mail"
	"net/smtp"
	"os"
)

// 解析地址 判断是否存在
func PathExists(path string) (bool, error) {
	// os.Stat 返回描述文件的fileinfo，如果指定的文件对象是一个符号链接，返回的是fileinfo描述该符号的文件信息，本函数会尝试跳转到该链接
	// 返回的err 为nil  表示文件夹存在
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	// os.IsNotExist(err) 返回true表示文件不存在
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// 加密
func Encrypt(plaintext []byte, keystring string) ([]byte, error) {

	//	 kry
	key := []byte(keystring)
	// 创建 AES密码
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	//	 16+ 明文长度字符串
	// 在开始的时候加上 IV
	ciphertext := make([]byte, aes.BlockSize+len(keystring))
	//	前16个的切片
	iv := ciphertext[:aes.BlockSize]
	//	 写入16为兰特字节填充iv
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return nil, err
	}
	//  返回加密的流
	decrypter := cipher.NewCFBEncrypter(block, iv)
	// 将字节从明文加密为密文
	decrypter.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)

	return ciphertext, nil
}

// 设置md5
func Md5(soure string) string {
	hash := md5.New()
	hash.Write([]byte(soure))

	return hex.EncodeToString(hash.Sum(nil))
}

// 获取uuid
func UUID() string {
	return uuid.Rand().Hex()
}

// 发送邮件
// user 登录的邮箱号
// password 不是qq邮箱密码,需要登陆你的qq邮箱，在设置，账号，启用IMAP/SMTP服务，会发送一段身份验证符号给你，用这个登陆
// host:smtp.qq.com:587
// to:加入多个邮箱,已逗号隔开,相当于群发。
// subject:发送的主题
// body:发送的内容
// mailtyoe: 发送的内容是文本还是html
func SendToMail(user, password, servername, to, subject, body, mailtype string) error {
	userEmail := mail.Address{"", user}
	toEmail := mail.Address{"", user}
	// 邮件发送的头部
	// Setup headers
	headers := make(map[string]string)
	headers["From"] = user
	headers["To"] = to
	headers["Subject"] = subject
	// 建立消息
	// Setup message
	message := ""
	for k, v := range headers {
		message += fmt.Sprintf("%s: %s\r\n", k, v)
	}
	message += "\r\n" + body
	host, _, _ := net.SplitHostPort(servername)
	auth := smtp.PlainAuth("", user, "vqbqdbvzhlvrbebf", host)
	// TLS 配置
	tlsconfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         host,
	}
	//这是钥匙，你需要叫tls。拨号而不是smtp.Dial
	//用于运行在465上的需要ssl连接的smtp服务器
	//从一开始(没有starttls)
	conn, err := tls.Dial("tcp", servername, tlsconfig)
	if err != nil {
		log.Panic(err)
	}

	c, err := smtp.NewClient(conn, host)
	if err != nil {
		log.Panic(err)
	}
	// 认证
	if err = c.Auth(auth); err != nil {
		log.Panic(err)
	}
	if err = c.Mail(userEmail.Address); err != nil {
		log.Panic(err)
	}

	if err = c.Rcpt(toEmail.Address); err != nil {
		log.Panic(err)
	}
	// Data
	w, err := c.Data()
	if err != nil {
		log.Panic(err)
	}

	_, err = w.Write([]byte(message))
	if err != nil {
		log.Panic(err)
	}

	err = w.Close()
	if err != nil {
		log.Panic(err)
	}
	return c.Quit()

}
